import Interface.MyInterfaceAbstract;
import Interface.MyInterfaceAbstractImplA;
import Interface.MyInterfaceAbstractImplB;

/**
    接口就是多个类的公共规范。接口是一种引用数据类型，最重要的内容就是其中的：抽象方法。

    如何定义一个接口的格式：
    public interface 接口名称 {}
    备注：换成了关键字interface之后，编译生成的字节码文件仍然是：.java --> .class。

    Java 7，那么接口中可以包含的内容有：
        1. 常量
        2. 抽象方法
    Java 8，还可以额外包含有：
        3. 默认方法
            1) 接口的默认方法，可以通过接口实现类对象，直接调用。
            2) 接口的默认方法，也可以被接口实现类进行覆盖重写。
        4. 静态方法
            1）接口的静态方法，不能通过接口的实现对象调用；
            2）接口的静态方法，只能通过接口名称直接调用静态方法。
    Java 9，还可以额外包含有：
        5. 私有方法

    接口使用步骤：
        1. 接口不能直接使用，必须有一个“实现类”来“实现”该接口。格式：
            public class 实现类名称 implements 接口名称 {...}
        2. 接口的实现类必须覆盖重写（实现）接口中所有的抽象方法。
        3. 创建实现类的对象，进行使用。

    接口的注意事项:☆☆☆☆☆☆
        1. 接口是没有静态代码块或者构造方法的。
        2. 一个类的直接父类是唯一的，但是一个类可以同时实现多个接口。
        3. 接口与接口之间是多继承的。
        4. 实现的多个接口存在重复的抽象方法，只需要覆盖重写一次即可。
        5. 实现类没有重写所有抽象方法，那么实现类就必须是一个抽象类。
        6. 如果实现类实现的多个接口存在重复的默认方法，那么实现类一定要对冲突的默认方法进行重写。
        7. 一个类继承父类当中的方法，和接口当中的默认方法产生了冲突，优先用父类当中的方法
 */
public class Demo01Interface {
    public static void main(String[] args) {
        // 错误写法！不能直接new接口对象使用。
//        MyInterfaceAbstract inter = new MyInterfaceAbstract();

        System.out.println(MyInterfaceAbstract.NUM_OF_MY_CLASS);//常量
        /*------实现接口的实现类的对象使用----------*/
        MyInterfaceAbstractImplA implA = new MyInterfaceAbstractImplA();
        implA.methodAbs1();
        implA.methodAbs2();

        /*------默认方法的使用----------------*/
        implA.methodDefault(); // 调用默认方法，如果实现类当中没有，会向上找接口
        System.out.println("-------------------");

        MyInterfaceAbstractImplB implB = new MyInterfaceAbstractImplB();
        implB.methodAbs1();
        implB.methodDefault(); // 实现类B覆盖重写了接口的默认方法


        /*------静态方法的使用-----------------*/
        // 错误写法！
//        implA.methodStatic();
        // 直接通过接口名称调用静态方法
        MyInterfaceAbstract.methodStatic();

        /*----私有方法的使用看 MyInterfacePrivateA.java 看看就行了-------------*/
    }
}
